package it.softphone.cmc.server.entity;

import it.softphone.cmc.shared.entity.Attributes;
import it.softphone.cmc.shared.entity.Version;
import it.softphone.commons.service.LogAware;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.persistence.CascadeType;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;


/**
 * 
 * @author bsorrentino
 *
 */
@Entity
public class VersionEntity implements Version,LogAware,Comparable<Object> {

	final public static Pattern pattern = Pattern.compile( "(\\d+)(?:[.](\\d+))?(?:[.](\\d+))?" );

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY) 
	private Long id;

	private java.lang.String version;
	private java.util.Date releaseDate = new java.util.Date();

	@Embedded 
	@OneToOne(cascade=CascadeType.ALL)
	private AttributesEntity attributes = new AttributesEntity();
	
	@Override
	public java.util.Date getReleaseDate() {
		return releaseDate;
	}

	@Override
	public void setReleaseDate(java.util.Date releaseDate) {
		this.releaseDate = releaseDate;
	}

	@Override
	public String toString() {

		return new StringBuilder()
				.append("id=").append(getId())
				.append("version=").append(getVersion())
				.append("date=").append(getReleaseDate())
				.toString();
	}

	@Override
	public Long getId() {
		return id;
	}

	@Override
	public void setId(Long id) {
		this.id = id;
	}

	@Override
	public java.lang.String getVersion() {
		return version;
	}

	@Override
	public void setVersion(java.lang.String version) {
		if( version!=null && !pattern.matcher(version).matches() ) throw new IllegalArgumentException("version is not valid format!");
		
		this.version = version;
	}

	@Override
	public Attributes getAttributes() {
		return attributes;
	}

	@Override
	public void setAttributes(Attributes value) {
		attributes = (AttributesEntity) value;
		
	}

	@SuppressWarnings("unchecked")
	@Override
	public it.softphone.commons.json.server.JSONObject encodeAttributes() {	
		return  attributes.encodeAttributes();
	}

	@Override
	public void decodeAttributes(Object object) {
		attributes.decodeAttributes(object);
	}

	@Override
	public int compareTo(Object o) {
		
		final String version = getVersion();
		
		String s = null;
		
		if( o instanceof String ) {
			s = (String) o;
		}
		else if( o instanceof Version ) {
			
			s = ((Version) o).getVersion();
			
		}
		
		if( version == null && s == null ) return 0;
		if( version == null && s != null ) return -1;
		if( version != null && s == null ) return 1;
		
		Matcher mToCompare = pattern.matcher(s);
		
		if( !mToCompare.matches() ) return 1;
		
		Matcher mMe = pattern.matcher(version);
		
		mMe.matches(); // assert to be valid
		
		//int groupsSelf = mMe.groupCount();
		
		//int groupsToCompare = mToCompare.groupCount();

		//System.out.printf( "groupsSelf=[%d] - groupsToCompare=[%d]\n", groupsSelf, groupsToCompare );
		
		//int groupsCount = Math.min(groupsToCompare, groupsSelf);
		
		for( int i = 1 ; i <= 3 ; ++i ) {
			String gToCompare	= mToCompare.group(i);
			String gMe 			= mMe.group(i);
			
			//System.out.printf( "mToCompare.group(%d)=[%s] -  mMe.group(%d)=[%s]\n", i, gToCompare, i,  gMe );
			
			if( gMe != null && gToCompare == null ) return 1;
			if( gMe == null && gToCompare != null ) return -1;
			if( gMe == null && gToCompare == null ) return 0;
						
			int r = Integer.parseInt(gMe) - Integer.parseInt(gToCompare);
			
			if( r != 0 ) return r;
		}
		
		return 0;
		
	}
}
